home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / c / bplus25a.zip / BPLUS.C next >
Text File  |  1991-06-14  |  26KB  |  1,004 lines

  1. /********************************************************************/
  2. /*                                                                  */
  3. /*             BPLUS file indexing program - Version 2.5            */
  4. /*                                                                  */
  5. /*                      A "shareware program"                       */
  6. /*                                                                  */
  7. /*                                                                  */
  8. /*                    Copyright (C) 1987-1991 by                    */
  9. /*                                                                  */
  10. /*                      Hunter and Associates                       */
  11. /*                      7900 Edgewater Drive                        */
  12. /*                      Wilsonville, Oregon  97070                  */
  13. /*                      (503) 694 - 1449                            */
  14. /*                                                                  */
  15. /********************************************************************/
  16.  
  17.  
  18. #include <stdio.h>
  19. #include <fcntl.h>
  20. #include <io.h>
  21. #include <process.h>
  22. #include <sys\types.h>            /*  delete this line for Turbo C  */
  23. #include <sys\stat.h>
  24. #include <string.h>
  25. #include "bplus.h"
  26.  
  27.  
  28. /*  macros, constants, data types  */
  29.  
  30. #define  NULLREC      (-1L)
  31. #define  FREE_BLOCK   (-2)
  32.  
  33. #define  ENT_ADR(pb,off)  ((ENTRY*)((char*)((pb)->entries) + off))
  34. #define  ENT_SIZE(pe)     strlen((pe)->key) + 1 + 2 * sizeof(RECPOS)
  35. #define  BUFDIRTY(j)      (mci->cache[j].dirty)
  36. #define  BUFHANDLE(j)     (mci->cache[j].handle)
  37. #define  BUFBLOCK(j)      (mci->cache[j].mb)
  38. #define  BUFCOUNT(j)      (mci->cache[j].count)
  39. #define  CB(j)            (pci->pos[j].cblock)
  40. #define  CO(j)            (pci->pos[j].coffset)
  41. #define  TRUE             1
  42. #define  FALSE            0
  43.  
  44.                                     /* BPLUS uses the library routine    */
  45.                                     /* memmove which must be used with   */
  46.                     /* Turboc 1.5, 2.0, Quick C and      */
  47.                     /* MS C 5.0 and 5.1                  */
  48. /* #define memmove    memcpy */     /* Use this macro for Microsoft C4.0 */
  49.  
  50. /*  declare some global variables  */
  51.  
  52. IX_DESC      *pci;
  53. IX_BUFFER    bt_buffer;
  54. IX_BUFFER    *mci = &bt_buffer;
  55. BLOCK        *block_ptr;
  56. BLOCK        *spare_block;
  57. int          cache_ptr = 0;
  58. int          cache_init = 0;
  59. int          split_size = IXB_SPACE;
  60. int          comb_size  = (IXB_SPACE/2);
  61.  
  62. void pascal error(int, long);
  63. void pascal read_if(long, char *, int);
  64. void pascal write_if(int, long, char *, int);
  65. void pascal reset_buffers(IX_DESC *);
  66. int  pascal creat_if(char *);
  67. int  pascal open_if(char *);
  68. void pascal close_if(int);
  69. void pascal update_block(void);
  70. void pascal init_cache(void);
  71. int  pascal find_cache(RECPOS);
  72. int  pascal new_cache(void);
  73. void pascal load_cache(RECPOS);
  74. void pascal get_cache(RECPOS);
  75. void pascal retrieve_block(int, RECPOS);
  76. int  pascal prev_entry(int);
  77. int  pascal next_entry(int);
  78. void pascal copy_entry(ENTRY *, ENTRY *);
  79. int  pascal scan_blk(int);
  80. int  pascal last_entry(void);
  81. void pascal write_free( RECPOS, BLOCK *);
  82. RECPOS pascal get_free(void);
  83. int  pascal find_block(ENTRY *, int *, int *);
  84. void pascal movedown(BLOCK *, int, int);
  85. void pascal moveup(BLOCK *, int, int);
  86. void pascal ins_block(BLOCK *, ENTRY *, int);
  87. void pascal del_block(BLOCK *, int);
  88. void pascal split(int, ENTRY *, ENTRY *);
  89. void pascal ins_level(int, ENTRY *);
  90. int  pascal insert_ix(ENTRY *, IX_DESC *);
  91. int  pascal find_ix(ENTRY *, IX_DESC *, int);
  92. int  pascal combineblk(RECPOS, int);
  93. void pascal replace_entry(ENTRY *);
  94. void print_blk(BLOCK *);
  95.  
  96.  
  97. /*  file I/O for B-PLUS module  */
  98.  
  99. void pascal error(j, l)
  100.   int j;
  101.   long l;
  102.   {
  103.     static char *msg[3] = {"ERROR - CANNOT OPEN/CLOSE FILE",
  104.                            "ERROR WHILE READING FILE",
  105.                            "ERROR WHILE WRITING FILE"};
  106.     printf("\n  %s - Record Number %ld\n", msg[j], l);
  107.     exit(1);
  108.   } /* error */
  109.  
  110.  
  111. void pascal read_if(start, buf, nwrt)
  112.   long start;
  113.   char *buf;
  114.   int nwrt;
  115.   {
  116.     long err;
  117.     err = start - lseek(pci->ixfile, start, SEEK_SET);
  118.     if (err == 0) err = nwrt - read(pci->ixfile, buf, nwrt);
  119.     if (err != 0) error(1, start);
  120.   } /* read_if */
  121.  
  122.  
  123. void pascal write_if(handle, start, buf, nwrt)
  124.   int handle;
  125.   long start;
  126.   char *buf;
  127.   int nwrt;
  128.   {
  129.     long err;
  130.     err = start - lseek(handle, start, SEEK_SET);
  131.     if (err == 0) err = nwrt - write(handle, buf, nwrt);
  132.     if (err != 0) error(2, start);
  133.   } /* write_if */
  134.  
  135.  
  136. int pascal creat_if(fn)
  137.   char *fn;
  138.   {
  139.     int   ret;
  140.     ret = open(fn,O_RDWR|O_CREAT|O_TRUNC|O_BINARY,S_IWRITE);
  141.     if (ret  < 0) error(0,0L);
  142.     return (ret);
  143.   } /* creat_if */
  144.  
  145.  
  146. int pascal open_if(fn)
  147.   char *fn;
  148.   {
  149.     int  ret;
  150.     ret = open(fn,O_RDWR|O_BINARY);
  151.     if (ret < 1) error(0,0L);
  152.     return (ret);
  153.   } /* open_if */
  154.  
  155.  
  156. void pascal close_if(handle)
  157.   int handle;
  158.   {
  159.     if(close(handle) < 0)  error(2,0L);
  160.   } /*  close_if */
  161.  
  162.  
  163. int cdecl open_index(name, pix, dup)
  164.   char *name;
  165.   IX_DESC *pix;
  166.   int dup;
  167.   {
  168.     pci = pix;
  169.     pci->ixfile = open_if(name);
  170.     pci->root_dirty = FALSE;
  171.     pci->duplicate = dup;
  172.     read_if(0L,(char *)&(pix->root), (sizeof(BLOCK) + sizeof(IX_DISK)));
  173.     if (!cache_init)
  174.       {
  175.         init_cache();
  176.         cache_init = 1;
  177.       }
  178.     return ( IX_OK );
  179.   } /* open_index */
  180.  
  181.  
  182. void cdecl buffer_flush(pix)
  183.   IX_DESC *pix;
  184. {
  185.   int i;
  186.   if (pix->root_dirty)
  187.   {
  188.     write_if(pix->ixfile, 0L,(char *)&(pix->root),
  189.                (sizeof(BLOCK) + sizeof(IX_DISK)));
  190.     pix->root_dirty = FALSE;
  191.   }
  192.   for (i = 0; i < NUM_BUFS; i++)
  193.   {
  194.     if ( (BUFHANDLE(i) == pix->ixfile) && BUFDIRTY(i) )
  195.     {
  196.       write_if(BUFHANDLE(i),
  197.            BUFBLOCK(i).brec,
  198.            (char *) &BUFBLOCK(i),
  199.            sizeof(BLOCK));
  200.       BUFDIRTY(i) = FALSE;
  201.     }
  202.   }
  203. }
  204.  
  205. void pascal reset_buffers(pix)
  206.   IX_DESC *pix;
  207.   {
  208.     int i;
  209.     for (i = 0; i < NUM_BUFS; i++)
  210.       if (BUFHANDLE(i) == pix->ixfile) BUFBLOCK(i).brec = NULLREC;
  211.   }
  212.  
  213.  
  214. int cdecl close_index(pix)
  215.   IX_DESC *pix;
  216.   {
  217.     int ret = IX_OK;
  218.     buffer_flush(pix);
  219.     reset_buffers(pix);
  220.     close_if(pix->ixfile);
  221.     return( ret );
  222.   } /* close_index */
  223.  
  224.  
  225. int cdecl make_index(name, pix, dup)
  226.   char *name;
  227.   IX_DESC *pix;
  228.   int dup;
  229.   {
  230.     pci = pix;
  231.     pci->ixfile = creat_if(name);
  232.     pci->duplicate = dup;
  233.     pci->root_dirty = FALSE;
  234.     pci->dx.nl = 1;
  235.     pci->dx.ff = NULLREC;
  236.     pci->level = 0;
  237.     CO(0) = -1;
  238.     CB(0) = 0L;
  239.     pci->root.brec = 0L;
  240.     pci->root.bend = 0;
  241.     pci->root.p0 = NULLREC;
  242.     write_if(pci->ixfile, 0L,(char *)&(pix->root),
  243.                (sizeof(BLOCK) + sizeof(IX_DISK)));
  244.     if (!cache_init)
  245.       {
  246.         init_cache();
  247.         cache_init = 1;
  248.       }
  249.     return ( IX_OK );
  250.   } /* make_index */
  251.  
  252.  
  253. /*  cache I/O for BPLUS  */
  254.  
  255. void pascal update_block()
  256.   {
  257.     if (block_ptr == &(pci->root)) pci->root_dirty = TRUE;
  258.     else  BUFDIRTY(cache_ptr) = TRUE;
  259.   } /* update_block */
  260.  
  261.  
  262. void pascal init_cache()
  263.   {
  264.     register int  j;
  265.     for (j = 0; j < NUM_BUFS; j++)
  266.       {  BUFDIRTY(j) = 0;
  267.          BUFCOUNT(j) = 0;
  268.          BUFBLOCK(j).brec = NULLREC;
  269.       }
  270.   } /* init_cache */
  271.  
  272.  
  273. int pascal find_cache(r)
  274.   RECPOS r;
  275.   {
  276.     register int  j;
  277.     for (j = 0; j < NUM_BUFS; j++)
  278.       {
  279.         if((BUFBLOCK(j).brec == r) && (BUFHANDLE(j) == pci->ixfile))
  280.          {  cache_ptr = j;
  281.             return (1);
  282.       }  }
  283.     return (-1);
  284.   } /* find_cache */
  285.  
  286.  
  287. int pascal new_cache()
  288.   {
  289.     register int  i;
  290.     i = (cache_ptr + 1) % NUM_BUFS;
  291.     if (BUFDIRTY(i)) write_if(BUFHANDLE(i),
  292.                               BUFBLOCK(i).brec,
  293.                               (char *) &BUFBLOCK(i),
  294.                               sizeof(BLOCK));
  295.     BUFHANDLE(i) = pci->ixfile;
  296.     BUFDIRTY(i) = 0;
  297.     return (i);
  298.   } /* new_cache */
  299.  
  300.  
  301. void pascal load_cache(r)
  302.   RECPOS r;
  303.